{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "19dda391-ef5b-4d6b-b4ba-0c0233c37c88",
   "metadata": {
    "id": "YSPItBwWZQgO"
   },
   "source": [
    "# Function Calling"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f209c88-7648-43ae-a298-7547dc5e7a63",
   "metadata": {},
   "source": [
    "### Housekeeping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a621b684-4812-4a8b-b094-42821858feae",
   "metadata": {
    "height": 166
   },
   "outputs": [],
   "source": [
    "def afunction(arg1:int = 0, arg2:str = \"hello\", **kwargs)->int:\n",
    "    ''' this is a function definition\n",
    "        arg1 (int): an exemplary yet modest argument\n",
    "        arg2 (str): another nice argument\n",
    "        **kwargs : the rest of the rabble \n",
    "\n",
    "        returns arg1 incremented by one\n",
    "    '''\n",
    "    return(arg + 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6367f5be-bbe9-49c8-95c5-b891cf0b0b53",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "print(afunction.__name__)\n",
    "print(afunction.__doc__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a8a45a6-fc1e-414d-90e0-d9475e8e5130",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "import inspect\n",
    "print(inspect.signature(afunction))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa1a1ee7-90fa-4816-bf99-606e34e9dd8d",
   "metadata": {},
   "source": [
    "##### Building User Query\n",
    "> Note, the video shows how to access utils.py in Jupyter Notebook V7.   \n",
    "> You may be in Jupyter Notebook V6. To access it in this version, on the menu, choose File->Open. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f819feaf-1f55-4550-8089-bb9e677ab68b",
   "metadata": {
    "height": 353
   },
   "outputs": [],
   "source": [
    "import inspect\n",
    "def build_raven_prompt(function_list, user_query):\n",
    "    raven_prompt = \"\"\n",
    "    for function in function_list:\n",
    "        signature = inspect.signature(function)\n",
    "        docstring = function.__doc__\n",
    "        prompt = \\\n",
    "f'''\n",
    "Function:\n",
    "def {function.__name__}{signature}\n",
    "    \"\"\"\n",
    "    {docstring.strip()}\n",
    "    \"\"\"\n",
    "    \n",
    "'''\n",
    "        raven_prompt += prompt\n",
    "        \n",
    "    raven_prompt += f\"User Query: {user_query}<human_end>\"\n",
    "    return raven_prompt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "158f8a7e-d20f-464f-b3f0-e95c5fae5765",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print( build_raven_prompt([afunction], \"a query\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0a64ddc-9c06-421e-935b-483985625692",
   "metadata": {
    "id": "6mX9gi3Ofj5r"
   },
   "source": [
    "### Concrete Example For Parallel Calls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "86a648f7-0733-4156-8e8b-5642cda45bf1",
   "metadata": {
    "height": 132
   },
   "outputs": [],
   "source": [
    "from utils import draw_clown_face\n",
    "\n",
    "raven_msg = \"Hey, can you build me two clowns.\" \\\n",
    "\"The first clown should be red faced, with a blue nose\" \\\n",
    "\"and a mouth from 0 to 180 degrees. The mouth should be black.\" \\\n",
    "\"The second clown should have a blue face and a green nose\" \\\n",
    "\"and a red mouth that's 180 to 360 degrees.\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f5dbc18-dac3-43aa-af6e-286121405872",
   "metadata": {},
   "source": [
    "#### Building Raven Prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5630ea1c-7d71-46ff-9e88-59602ca4941d",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "height": 64,
    "id": "IThyr1tRfmey",
    "outputId": "79bc063a-3aef-4776-c71e-302e7e638121"
   },
   "outputs": [],
   "source": [
    "raven_prompt = build_raven_prompt([draw_clown_face], raven_msg)\n",
    "\n",
    "print (raven_prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1e3e2db9-0696-4978-a42b-7e6038e00733",
   "metadata": {
    "height": 81
   },
   "outputs": [],
   "source": [
    "from utils import query_raven\n",
    "raven_call = query_raven(raven_prompt)\n",
    "print (raven_call)\n",
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8461ad6-82b1-4b1b-bec4-f17f684b85f5",
   "metadata": {},
   "source": [
    "### Using Multiple Functions!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbc15476-312c-423a-b62b-136855f7985c",
   "metadata": {},
   "source": [
    "#### Building The Prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3068564c-d53a-43d8-91d5-5dba9ed17632",
   "metadata": {
    "height": 81,
    "tags": []
   },
   "outputs": [],
   "source": [
    "from utils import draw_clown_face, draw_tie\n",
    "raven_msg = \"Hey draw a tie?\"\n",
    "raven_prompt = build_raven_prompt\\\n",
    "    ([draw_clown_face, draw_tie], raven_msg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e5bcc88e-5ad3-48a6-b933-fd7f75fd972a",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print(raven_prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c424524-99d0-4c95-823f-d67298d2a42a",
   "metadata": {},
   "source": [
    "#### Getting The Call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1416f63-e4e2-4018-b9b5-02d997754fde",
   "metadata": {
    "height": 47,
    "tags": []
   },
   "outputs": [],
   "source": [
    "raven_call = query_raven(raven_prompt)\n",
    "print (raven_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "049e2d91-ec3c-4554-ac5b-6bdaf54a00cc",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3378221-d823-4e30-891b-85d203ec7632",
   "metadata": {},
   "source": [
    "### Multiple Parallel Function Calling"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "588f02da-cdc5-4962-8347-b49af45ccc7d",
   "metadata": {},
   "source": [
    "#### Build The Prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b2a110d-f609-42ee-b429-9a5393816f84",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "raven_msg = \"Draw a clown and a tie?\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4a36415a-f8e4-42d6-9e5d-03e462a103ef",
   "metadata": {
    "height": 47,
    "tags": []
   },
   "outputs": [],
   "source": [
    "raven_prompt = build_raven_prompt([draw_tie, draw_clown_face], raven_msg)\n",
    "raven_call = query_raven(raven_prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48dc87c0-1e26-4ed0-b03a-16e03f6022ad",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "print (raven_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d67c74b1-38b4-4703-8f59-d0a96703b278",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "633894d1-9733-40e9-8d64-29f63db29b6c",
   "metadata": {},
   "source": [
    "### What is the significance of the docstrings?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abdfd941-d837-4f4e-8a66-f95b52f0e500",
   "metadata": {
    "height": 98,
    "tags": []
   },
   "outputs": [],
   "source": [
    "raven_msg = \"Draw me a sad one with green head\"\n",
    "raven_prompt = build_raven_prompt([draw_clown_face], raven_msg)\n",
    "raven_call = query_raven(raven_prompt)\n",
    "print (raven_call)\n",
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f05aa8d4-573f-4656-867b-b0cc0464e879",
   "metadata": {},
   "source": [
    "#### Fixing The Function Docstring"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5eeadbcd-d63c-4a05-a442-7c616458be14",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "print (raven_prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b62f8395-1b44-4ed2-856e-bc3b804bd951",
   "metadata": {
    "height": 489
   },
   "outputs": [],
   "source": [
    "raven_prompt_targeted = \\\n",
    "'''\n",
    "Function:\n",
    "def draw_clown_face(face_color='yellow', eye_color='black', nose_color='red', eye_size=0.05, mouth_size=(0.3, 0.1), mouth_color='black', eye_offset=(0.15, 0.15), mouth_theta=(200, 340))\n",
    "    \"\"\"\n",
    "    Draws a customizable, simplified clown face using matplotlib.\n",
    "\n",
    "    Parameters:\n",
    "    - face_color (str): Color of the clown's face. Default is 'yellow'.\n",
    "    - eye_color (str): Color of the clown's eyes. Default is 'black'.\n",
    "    - nose_color (str): Color of the clown's nose. Default is 'red'.\n",
    "    - eye_size (float): Radius of the clown's eyes. Default is 0.05.\n",
    "    - mouth_size (tuple): Width and height of the clown's mouth arc. Default is (0.3, 0.1).\n",
    "    - eye_offset (tuple): Horizontal and vertical offset for the eyes from the center. Default is (0.15, 0.15).\n",
    "    - mouth_theta (tuple): Controls the emotions of the clown. Starting and ending angles (in degrees) of the mouth arc. Default is (200, 340).\n",
    "\n",
    "    This function creates a plot displaying a simplified clown face, where essential facial features' size, position, and color can be customized. \n",
    "\n",
    "    Example usage:\n",
    "    draw_clown_face(face_color='lightblue', eye_color='green', nose_color='orange', \n",
    "                    eye_size=0.07, mouth_size=(0.4, 0.25), \n",
    "                    eye_offset=(0.2, 0.2), mouth_theta=(0, 180))\n",
    "\n",
    "    # This will draw a simplified clown face with a light blue face, green eyes, an orange nose, and a smiling mouth.\n",
    "    \"\"\"\n",
    "    \n",
    "User Query: Draw me a sad one with green head<human_end>\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93c61030-f3f0-48f5-99a8-d96a95edc039",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "raven_call = query_raven(raven_prompt_targeted)\n",
    "print (raven_call)\n",
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "578ec52e-57dc-405f-9d9d-e5880367bdb7",
   "metadata": {
    "id": "yIK9qpfSacEE"
   },
   "source": [
    "### Concrete Example For Nested APIs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "975a5c18-2766-4380-a6b9-1b34f6799790",
   "metadata": {
    "height": 81,
    "tags": []
   },
   "outputs": [],
   "source": [
    "raven_msg_nested = \"Hey draw me a clown with \"\\\n",
    "                    \"a red face, blue eyes, green nose, \"\\\n",
    "                    \"and a black mouth open from 0 to 360 \"\\\n",
    "                    \"degrees?\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b4a79fc5-b63c-43c4-976e-f3c4ff835e07",
   "metadata": {
    "height": 183,
    "id": "kcGq73hRYlwX"
   },
   "outputs": [],
   "source": [
    "from utils import draw_head, draw_eyes, \\\n",
    "    draw_nose, draw_mouth, \\\n",
    "    draw_clown_face_parts\n",
    "raven_function_nested = build_raven_prompt([draw_head, \\\n",
    "                                            draw_eyes, \\\n",
    "                                            draw_nose, \\\n",
    "                                            draw_mouth, \\\n",
    "                                            draw_clown_face_parts],\\\n",
    "                                            raven_msg_nested)\n",
    "raven_call = query_raven(raven_function_nested)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9385d37d-61c3-4eaf-811f-ee2ea3290fe9",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "height": 30,
    "id": "AeAzs29PeHAl",
    "outputId": "26ea8920-96e5-4f16-905f-a7203c42be9a"
   },
   "outputs": [],
   "source": [
    "print (raven_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffa9cffb-f2ed-4ae4-b6fc-0a61f39f2242",
   "metadata": {
    "height": 30,
    "tags": []
   },
   "outputs": [],
   "source": [
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b82a427-18bd-4c73-af08-b0932fe33596",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
